package com.iwomy.secureplat.platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iwomy.secureplat.common.core.constant.CacheConstants;
import com.iwomy.secureplat.common.data.datascope.DataScope;
import com.iwomy.secureplat.platform.dto.AlarmRulesDTO;
import com.iwomy.secureplat.platform.dto.AlarmRulesDetailsDTO;
import com.iwomy.secureplat.platform.entity.*;
import com.iwomy.secureplat.platform.enumeration.StateEnum;
import com.iwomy.secureplat.platform.mapper.AlarmRulesMapper;
import com.iwomy.secureplat.platform.service.AlarmDeviceRulesService;
import com.iwomy.secureplat.platform.service.AlarmRulesDetailsService;
import com.iwomy.secureplat.platform.service.AlarmRulesService;
import com.iwomy.secureplat.platform.vo.AlarmRulesDetailsVO;
import com.iwomy.secureplat.platform.vo.AlarmRulesVO;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 告警规则
 *
 * @author pig
 * @date 2023-12-22 10:09:21
 */
@Service
public class AlarmRulesServiceImpl extends ServiceImpl<AlarmRulesMapper, AlarmRulesEntity> implements AlarmRulesService {
	@Resource
	private AlarmRulesDetailsService alarmRulesDetailsService;
	@Resource
	private AlarmDeviceRulesService alarmDeviceRulesService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean savaAlarmRules(AlarmRulesDTO alarmRulesDTO) {
		List<AlarmRulesDetailsDTO> alarmRulesDetailsList = alarmRulesDTO.getAlarmRulesDetailsList();
		List<AlarmRulesDetailsEntity> alarmRulesDetailsEntities = BeanUtil.copyToList(alarmRulesDetailsList, AlarmRulesDetailsEntity.class);

		StringBuffer sb = new StringBuffer();
		alarmRulesDetailsEntities.stream().forEach(x -> {
			sb.append("para").append(x.getOperator())
					.append(x.getThreshold())
					.append(StrUtil.isEmpty(x.getLogicalOperator()) ? "" : x.getLogicalOperator());
		});
		AlarmRulesEntity alarmRulesEntity = BeanUtil.copyProperties(alarmRulesDTO, AlarmRulesEntity.class);
		alarmRulesEntity.setCalcExpression(sb.toString());
		save(alarmRulesEntity);
		Long id = alarmRulesEntity.getId();
		for (AlarmRulesDetailsEntity alarmRulesDetailsEntity : alarmRulesDetailsEntities) {
			alarmRulesDetailsEntity.setAlarmRulesId(id);
		}

		return alarmRulesDetailsService.saveBatch(alarmRulesDetailsEntities);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateAlarmRulesById(AlarmRulesDTO alarmRulesDTO) {
		AlarmRulesEntity alarmRulesEntity = BeanUtil.copyProperties(alarmRulesDTO, AlarmRulesEntity.class);

		LambdaQueryWrapper<AlarmRulesDetailsEntity> alarmRulesDetailsEntityLambdaQueryWrapper = Wrappers.lambdaQuery();
		Long id = alarmRulesEntity.getId();
		alarmRulesDetailsEntityLambdaQueryWrapper.eq(AlarmRulesDetailsEntity::getAlarmRulesId, id);
		alarmRulesDetailsService.remove(alarmRulesDetailsEntityLambdaQueryWrapper);
		List<AlarmRulesDetailsDTO> alarmRulesDetailsList = alarmRulesDTO.getAlarmRulesDetailsList();
		List<AlarmRulesDetailsEntity> alarmRulesDetailsEntities = BeanUtil.copyToList(alarmRulesDetailsList, AlarmRulesDetailsEntity.class);
		StringBuffer sb = new StringBuffer();

		for (AlarmRulesDetailsEntity alarmRulesDetailsEntity : alarmRulesDetailsEntities) {
			alarmRulesDetailsEntity.setAlarmRulesId(id);
			sb.append("para").append(alarmRulesDetailsEntity.getOperator())
					.append(alarmRulesDetailsEntity.getThreshold())
					.append(StrUtil.isEmpty(alarmRulesDetailsEntity.getLogicalOperator()) ? "" : alarmRulesDetailsEntity.getLogicalOperator());
		}
		alarmRulesEntity.setCalcExpression(sb.toString());
		updateById(alarmRulesEntity);
		return alarmRulesDetailsService.saveBatch(alarmRulesDetailsEntities);
	}

	@Override
	public AlarmRulesVO getAlarmRulesById(Long id) {

		AlarmRulesEntity alarmRulesEntity = this.getById(id);
		AlarmRulesVO alarmRulesVO = BeanUtil.copyProperties(alarmRulesEntity, AlarmRulesVO.class);
		LambdaQueryWrapper<AlarmRulesDetailsEntity> alarmRulesDetailsEntityLambdaQueryWrapper = Wrappers.lambdaQuery();
		alarmRulesDetailsEntityLambdaQueryWrapper.eq(AlarmRulesDetailsEntity::getAlarmRulesId, alarmRulesEntity.getId());
		List<AlarmRulesDetailsEntity> list = alarmRulesDetailsService.list(alarmRulesDetailsEntityLambdaQueryWrapper);
		List<AlarmRulesDetailsVO> alarmRulesDetailsVOS = BeanUtil.copyToList(list, AlarmRulesDetailsVO.class);
		alarmRulesVO.setAlarmRulesDetailsList(alarmRulesDetailsVOS);
		return alarmRulesVO;
	}

	@Override
	public List<AlarmRulesEntity> listBySensorIds(BasicDeviceEntity device, List<String> sensorIds) {
		LambdaQueryWrapper<AlarmRulesEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(AlarmRulesEntity::getState, StateEnum.ENABLE.getVal());
		queryWrapper.eq(AlarmRulesEntity::getDeviceModelId, device.getDeviceModelId());
		queryWrapper.eq(AlarmRulesEntity::getDeviceTypeId, device.getDeviceTypeId());
		queryWrapper.in(AlarmRulesEntity::getSensorTypeCode, sensorIds);
		return this.list(queryWrapper);
	}

	@Override
	@Cacheable(value = CacheConstants.EQUIPMENT_ALARM_RULES,key = "#device.imei")
	public List<AlarmRulesEntity> listByDevice(BasicDeviceEntity device) {
		LambdaQueryWrapper<AlarmDeviceRulesEntity> wrapper = Wrappers.lambdaQuery();
		List<AlarmDeviceRulesEntity> list = alarmDeviceRulesService
				.list(wrapper.eq(AlarmDeviceRulesEntity::getImei, device.getImei()));
		if (ObjectUtil.isEmpty(list)) return Collections.emptyList();
		List<Long> ruleIdList = list.stream().map(AlarmDeviceRulesEntity::getAlarmRulesId).collect(Collectors.toList());
		LambdaQueryWrapper<AlarmRulesEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(AlarmRulesEntity::getState,20).in(AlarmRulesEntity::getId,ruleIdList);
		return this.list(queryWrapper);
	}

	@Override
	public Page pageByScope(Page page, AlarmRulesEntity alarmRulesEntity) {
		LambdaQueryWrapper<AlarmRulesEntity> wrapper = Wrappers.lambdaQuery(alarmRulesEntity);
		return this.baseMapper.selectPageByScope(page, wrapper, new DataScope());
	}

	@Override
	public List<AlarmRulesEntity> listByScope(AlarmRulesEntity alarmRulesEntity) {
		LambdaQueryWrapper<AlarmRulesEntity> wrapper = Wrappers.lambdaQuery(alarmRulesEntity);
		return this.baseMapper.selectListByScope(wrapper, new DataScope());
	}
}